﻿#include"FITKAcousticsFESubSysElementListAdaptor.h"
#include "FITKAcousticsHDF5Writer.h"
#include "FITKAcousticsHDF5Reader.h"
#include "FITK_Interface/FITKInterfaceIO/FITKHDF5FileTool.h"
#include"FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementList.h"
#include"FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include"FITK_Interface/FITKInterfaceModel/FITKModelEnum.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementTri.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementLine.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementTri.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementQuad.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementTet.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementWedge.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementHex.h"
#include"FITK_Interface/FITKInterfaceModel/FITKElementPolygon.h"
#include<QHash>
bool IO::FITKAcousticsFESubSysElementListAdaptor::adaptR()
{
    if (m_FESubSysElementListP == nullptr || _reader == nullptr) return false;
    m_toolp = _reader->getHDF5FileTool();//初始化工具

    std::tuple<bool, H5::Group>Ret = m_toolp->openGp("FESubSysElementList");//打开FE单元列表组
    if (std::get<0>(Ret) == false) { return false; }
    H5::Group gp = std::get<1>(Ret);


    return this->readFESubSysElementList(gp, m_FESubSysElementListP);
}
bool IO::FITKAcousticsFESubSysElementListAdaptor::adaptW()
{
    if (m_FESubSysElementListP == nullptr)
    {
        return false;
    }

    if (m_FESubSysElementListP == nullptr || _writer == nullptr) return false;
    m_toolp = _writer->getHDF5FileTool();//初始化工具


    std::tuple<bool, H5::Group> Ret = m_toolp->createGp("FESubSysElementList");     //创建FE单元列表组
    if (std::get<0>(Ret) == false) { return false; }
    H5::Group gp = std::get<1>(Ret);

    return this->writeFESubSysElementList(gp, m_FESubSysElementListP);
}

void IO::FITKAcousticsFESubSysElementListAdaptor::setData(Acoustics::FITKAcousticsFESubSysElementList * FESubSysElementListP)
{
    if (FESubSysElementListP == nullptr)
    {
        m_FESubSysElementListP = nullptr;
        return;
    }
    m_FESubSysElementListP = FESubSysElementListP;
}

bool IO::FITKAcousticsFESubSysElementListAdaptor::readFESubSysElementList(H5::Group & gp, Acoustics::FITKAcousticsFESubSysElementList * FESubSysElementListP)
{
    if (FESubSysElementListP == nullptr)
    {
        return false;
    }
    std::vector<std::vector<int>>data;
    m_toolp->ReadTwoArrayDataSetInt(gp, "FESubSysElementList", data,"offset");

    for (int i = 0; i < data.size(); ++i)
    {
        std::vector<int>temp = data.at(i);
        if (temp.size()==0)
        {
            return false;
        }
        int type = temp[0];
        Interface::FITKModelEnum::FITKEleType eleType=this->InToEleType(type);


        //[0]type [1]eleID  [2]PropID  [3]enable  [n]所有节点
        Interface::FITKAbstractElement * ele=this->FromTypeCreateEleClass(eleType);//根据类型创建不同子类
        int eleID = temp[1];
        int PropID = temp[2];
        int isEnableInt = temp[3];
        QList<int>AllNodes;

        //前4个都为固定的，后面为长度不固定的节点
        for (int j = 4; j < temp.size(); ++j)
        {
            AllNodes.push_back(temp[j]);

        }
        ele->setEleID(eleID);
        ele->setNodeID(AllNodes);

        FESubSysElementListP->appendElement(ele);
        FESubSysElementListP->setElementPropID(eleID, PropID);
    }
    return true;
}

bool IO::FITKAcousticsFESubSysElementListAdaptor::writeFESubSysElementList(H5::Group & gp, Acoustics::FITKAcousticsFESubSysElementList * FESubSysElementListP)
{
    int count = FESubSysElementListP->getElementCount();
    std::vector<std::vector<int>>data;
    for (int i = 0; i < count; ++i)
    {
        Interface::FITKAbstractElement* ele = FESubSysElementListP->getElementAt(i);
        if (ele == nullptr)
        {
            return false;
        }
        Interface::FITKModelEnum::FITKEleType type = ele->getEleType();//类型
        int inttype =this->EleTypeFromInt(type);

        int eleID = ele->getEleID();//获取单元ID
        int PropID = FESubSysElementListP->getElementPropID(eleID);//根据ID获取属性ID
        QList<int>AllNodes = ele->getAllNodes();//全部节点
        bool isEnable = ele->isEnable();//是否enable
        int isEnableInt = isEnable == true ? 1 : 0;
        std::vector<int>temp;
        temp.push_back(inttype);
        temp.push_back(eleID);
        temp.push_back(PropID);
        temp.push_back(isEnableInt);
        for (int node : AllNodes)
        {
            temp.push_back(node);
        }
        data.push_back(temp);
        //type eleID PropID enable 所有节点
    }
    m_toolp->CreateTwoArrayDataSetInt(gp, "FESubSysElementList", data,"offset");
    return true;
}


int IO::FITKAcousticsFESubSysElementListAdaptor::EleTypeFromInt(Interface::FITKModelEnum::FITKEleType type)
{

    switch (type)
    {
    case Interface::FITKModelEnum::EleNone:
    {
        return -1;
        break;
    }

    case Interface::FITKModelEnum::Line2:
    {
        return 1;
        break;
    }
    case Interface::FITKModelEnum::Line3:
    {
        return 2;
        break;
    }
    case Interface::FITKModelEnum::Tri3:
    {
        return 3;
        break;
    }
    case Interface::FITKModelEnum::Tri6:
    {
        return 4;
        break;
    }
    case Interface::FITKModelEnum::Quad4:
    {
        return 5;
        break;
    }
    case Interface::FITKModelEnum::Quad8:
    {
        return 6;
        break;
    }
    case Interface::FITKModelEnum::Tet4:
    {
        return 7;
        break;
    }
    case Interface::FITKModelEnum::Tet10:
    {
        return 8;
        break;
    }
    case Interface::FITKModelEnum::Wedge6:
    {
        return 10;
        break;
    }
    case Interface::FITKModelEnum::Hex8:
    {
        return 11;
        break;
    }
    case Interface::FITKModelEnum::Hex20:
    {
        return 12;
        break;
    }
    case Interface::FITKModelEnum::Polygon:
    {
        return 13;
        break;
    }
    default:
    {
        return -2;
        break;
    }
    }

    return -2;
}

Interface::FITKModelEnum::FITKEleType IO::FITKAcousticsFESubSysElementListAdaptor::InToEleType(int type)
{

    if (type==-1)
    {
        return Interface::FITKModelEnum::EleNone;
    }
    else if (type == 1)
    {
        return Interface::FITKModelEnum::Line2;
    }
    else if (type == 2) {
        return Interface::FITKModelEnum::Line3;
    }
    else if (type == 3)
    {

        return Interface::FITKModelEnum::Tri3;
    }
    else if (type == 4) {
    
        return Interface::FITKModelEnum::Tri6;
    }
    else if (type == 5)
    {
        return Interface::FITKModelEnum::Quad4;
    }
    else if(type == 6)
    {
        return Interface::FITKModelEnum::Quad8;
    }
    else if (type == 7)
    {
        return Interface::FITKModelEnum::Tet4;
    }
    else if (type == 8)
    {
        return Interface::FITKModelEnum::Tet10;
    }
    else if (type == 10)
    {
        return Interface::FITKModelEnum::Wedge6;
    }
    else if (type == 11)
    {
        return Interface::FITKModelEnum::Hex8;

    }
    else if (type == 12)
    {
        return Interface::FITKModelEnum::Hex20;

    }
    else if (type == 13)
    {
        return Interface::FITKModelEnum::Polygon;
    }
    else
    {
        return Interface::FITKModelEnum::EleNone;
    }
   
}

Interface::FITKAbstractElement * IO::FITKAcousticsFESubSysElementListAdaptor::FromTypeCreateEleClass(Interface::FITKModelEnum::FITKEleType type)
{
    switch (type)
    {
    case Interface::FITKModelEnum::EleNone:
    {
        return nullptr;
        break;
    }
    case Interface::FITKModelEnum::Line2:
    {
        Interface::FITKElementLine2 *p = new Interface::FITKElementLine2;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Line3:
    {
        Interface::FITKElementLine3 *p = new Interface::FITKElementLine3;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Tri3:
    {
        Interface::FITKElementTri3 *p = new Interface::FITKElementTri3;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Tri6:
    {
        Interface::FITKElementTri6 *p = new Interface::FITKElementTri6;
        return p;
        break;
    
    }
    case Interface::FITKModelEnum::Quad4:
    {
        Interface::FITKElementQuad4 *p = new Interface::FITKElementQuad4;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Quad8:
    {
        Interface::FITKElementQuad8 *p = new Interface::FITKElementQuad8;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Tet4:
    {
        Interface::FITKElementTet4 *p = new Interface::FITKElementTet4;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Tet10:
    {
        Interface::FITKElementTet10 *p = new Interface::FITKElementTet10;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Wedge6:
    {
        Interface::FITKElementWedge6 *p = new Interface::FITKElementWedge6;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Hex8:
    {
        Interface::FITKElementHex8 *p = new Interface::FITKElementHex8;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Hex20:
    {
        Interface::FITKElementHex20 *p = new Interface::FITKElementHex20;
        return p;
        break;
    }
    case Interface::FITKModelEnum::Polygon:
    {
        Interface::FITKElementPolygon *p = new Interface::FITKElementPolygon;
        return p;
        break;
    }
    default:
        return nullptr;
        break;
    }
    return nullptr;
}
